using UnityEngine;
using System.Collections.Generic;
using XLua;
using System;

/// <summary>
/// Unity Lua战斗系统管理器
/// 负责与Lua Battle System的交互和Unity表现层的控制
/// </summary>
public class LuaBattleManager : MonoBehaviour
{
    [Header("XLua环境")]
    [SerializeField] private TextAsset[] luaScripts;
    private LuaEnv luaEnv;
    
    [Header("UI引用")]
    [SerializeField] private BattleUIManager battleUI;
    [SerializeField] private CharacterUIManager characterUI;
    [SerializeField] private SkillUIManager skillUI;
    
    [Header("战斗配置")]
    [SerializeField] private float battleSpeed = 1.0f;
    [SerializeField] private bool autoPlay = false;
    
    // 战斗状态
    private string currentBattleId;
    private BattleStateData currentBattleState;
    private bool isBattleActive = false;
    
    // 事件委托
    public event Action<BattleStateData> OnBattleStateChanged;
    public event Action<CharacterActionData> OnCharacterAction;
    public event Action<BattleResultData> OnBattleEnded;
    
    void Start()
    {
        InitializeLuaEnvironment();
        LoadLuaScripts();
        RegisterUnityCallbacks();
    }
    
    void OnDestroy()
    {
        CleanupLuaEnvironment();
    }
    
    /// <summary>
    /// 初始化Lua环境
    /// </summary>
    private void InitializeLuaEnvironment()
    {
        luaEnv = new LuaEnv();
        luaEnv.AddLoader(CustomLuaLoader);
        
        // 添加Unity类型到Lua环境
        luaEnv.Global.Set("UnityDebug", typeof(Debug));
        luaEnv.Global.Set("UnityTime", typeof(Time));
        luaEnv.Global.Set("UnityMathf", typeof(Mathf));
        
        Debug.Log("Lua环境初始化完成");
    }
    
    /// <summary>
    /// 自定义Lua加载器
    /// </summary>
    private byte[] CustomLuaLoader(ref string filepath)
    {
        // 查找Lua脚本文件
        foreach (var script in luaScripts)
        {
            if (script.name == filepath)
            {
                return script.bytes;
            }
        }
        return null;
    }
    
    /// <summary>
    /// 加载Lua脚本
    /// </summary>
    private void LoadLuaScripts()
    {
        try
        {
            // 加载Lua Battle System
            luaEnv.DoString("require('main')");
            
            // 加载桥接层
            luaEnv.DoString("require('lua_bridge')");
            
            Debug.Log("Lua脚本加载完成");
        }
        catch (System.Exception e)
        {
            Debug.LogError("Lua脚本加载失败: " + e.Message);
        }
    }
    
    /// <summary>
    /// 注册Unity回调函数
    /// </summary>
    private void RegisterUnityCallbacks()
    {
        // 注册各种战斗事件的Unity回调
        luaEnv.Global.Set("OnBattleStart", (Action<string, object, object>)OnBattleStartCallback);
        luaEnv.Global.Set("OnTurnStart", (Action<string, int>)OnTurnStartCallback);
        luaEnv.Global.Set("OnActionExecute", (Action<object, object>)OnActionExecuteCallback);
        luaEnv.Global.Set("OnCharacterDamage", (Action<string, int, int>)OnCharacterDamageCallback);
        luaEnv.Global.Set("OnCharacterHeal", (Action<string, int, int>)OnCharacterHealCallback);
        luaEnv.Global.Set("OnBattleEnd", (Action<string, object>)OnBattleEndCallback);
        luaEnv.Global.Set("OnSkillEffect", (Action<string, string, string>)OnSkillEffectCallback);
        luaEnv.Global.Set("OnStatusEffect", (Action<string, string, bool>)OnStatusEffectCallback);
        
        // 在Lua中注册这些回调
        luaEnv.DoString(@"
            local LuaBridge = require('lua_bridge')
            LuaBridge.register_callback('on_battle_start', OnBattleStart)
            LuaBridge.register_callback('on_turn_start', OnTurnStart)
            LuaBridge.register_callback('on_action_execute', OnActionExecute)
            LuaBridge.register_callback('on_character_damage', OnCharacterDamage)
            LuaBridge.register_callback('on_character_heal', OnCharacterHeal)
            LuaBridge.register_callback('on_battle_end', OnBattleEnd)
            LuaBridge.register_callback('on_skill_effect', OnSkillEffect)
            LuaBridge.register_callback('on_status_effect', OnStatusEffect)
        ");
        
        Debug.Log("Unity回调注册完成");
    }
    
    /// <summary>
    /// 开始战斗
    /// </summary>
    public void StartBattle(List<CharacterData> team1, List<CharacterData> team2)
    {
        try
        {
            // 转换Unity角色数据为Lua格式
            var luaTeam1 = ConvertCharacterDataToLua(team1);
            var luaTeam2 = ConvertCharacterDataToLua(team2);
            
            // 调用Lua开始战斗
            var battleSystem = luaEnv.Global.Get<LuaTable>("LuaBattleSystem");
            battleSystem.Get("init", Action<object>)();
            
            currentBattleId = (string)battleSystem.Get("start_battle", Func<object, object, string>)(luaTeam1, luaTeam2);
            isBattleActive = true;
            
            Debug.Log($"战斗开始，战斗ID: {currentBattleId}");
            
            // 如果是自动播放模式，开始执行战斗
            if (autoPlay)
            {
                StartCoroutine(AutoPlayBattle());
            }
        }
        catch (System.Exception e)
        {
            Debug.LogError("开始战斗失败: " + e.Message);
        }
    }
    
    /// <summary>
    /// 执行单个战斗回合
    /// </summary>
    public void ExecuteTurn()
    {
        if (!isBattleActive) return;
        
        try
        {
            var battleSystem = luaEnv.Global.Get<LuaTable>("LuaBattleSystem");
            var turnResult = battleSystem.Get("run_turn", Func<string, object>)(currentBattleId);
            
            // 更新战斗状态
            UpdateBattleState();
        }
        catch (System.Exception e)
        {
            Debug.LogError("执行战斗回合失败: " + e.Message);
        }
    }
    
    /// <summary>
    /// 获取当前战斗状态
    /// </summary>
    public void UpdateBattleState()
    {
        try
        {
            var battleSystem = luaEnv.Global.Get<LuaTable>("LuaBattleSystem");
            var battleState = battleSystem.Get("get_battle_state", Func<string, LuaTable>)(currentBattleId);
            
            // 通过Lua桥接层转换数据
            var luaBridge = luaEnv.Global.Get<LuaTable>("LuaBridge");
            currentBattleState = luaBridge.Get("create_battle_state_data", Func<LuaTable, BattleStateData>)(battleState);
            
            // 更新UI
            battleUI.UpdateBattleState(currentBattleState);
            characterUI.UpdateCharacters(currentBattleState);
            
            // 触发事件
            OnBattleStateChanged?.Invoke(currentBattleState);
        }
        catch (System.Exception e)
        {
            Debug.LogError("获取战斗状态失败: " + e.Message);
        }
    }
    
    /// <summary>
    /// 自动播放战斗
    /// </summary>
    private System.Collections.IEnumerator AutoPlayBattle()
    {
        while (isBattleActive)
        {
            ExecuteTurn();
            yield return new WaitForSeconds(1.0f / battleSpeed);
        }
    }
    
    /// <summary>
    /// 转换Unity角色数据为Lua格式
    /// </summary>
    private object ConvertCharacterDataToLua(List<CharacterData> characters)
    {
        var luaTable = luaEnv.NewTable();
        for (int i = 0; i < characters.Count; i++)
        {
            var charData = characters[i];
            var luaChar = luaEnv.NewTable();
            
            luaChar.Set("id", charData.id);
            luaChar.Set("name", charData.name);
            luaChar.Set("level", charData.level);
            luaChar.Set("max_hp", charData.maxHp);
            luaChar.Set("hp", charData.hp);
            luaChar.Set("max_mp", charData.maxMp);
            luaChar.Set("mp", charData.mp);
            luaChar.Set("attack", charData.attack);
            luaChar.Set("defense", charData.defense);
            luaChar.Set("magic_attack", charData.magicAttack);
            luaChar.Set("magic_defense", charData.magicDefense);
            luaChar.Set("speed", charData.speed);
            luaChar.Set("luck", charData.luck);
            luaChar.Set("team_id", charData.teamId);
            luaChar.Set("position", charData.position);
            luaChar.Set("is_controlled", charData.isControlled);
            
            luaTable.Set(i + 1, luaChar);
        }
        return luaTable;
    }
    
    // Unity回调函数实现
    private void OnBattleStartCallback(string battleId, object team1, object team2)
    {
        Debug.Log($"战斗开始回调: {battleId}");
        battleUI.ShowBattleStart(battleId);
    }
    
    private void OnTurnStartCallback(string battleId, int turn)
    {
        Debug.Log($"回合开始回调: {battleId}, 回合: {turn}");
        battleUI.ShowTurnStart(turn);
    }
    
    private void OnActionExecuteCallback(object character, object decision)
    {
        Debug.Log("角色行动回调");
        // 处理角色行动动画和效果
    }
    
    private void OnCharacterDamageCallback(string characterId, int damage, int currentHp)
    {
        Debug.Log($"角色受伤回调: {characterId}, 伤害: {damage}, 当前HP: {currentHp}");
        characterUI.ShowDamage(characterId, damage);
        characterUI.UpdateCharacterHP(characterId, currentHp);
    }
    
    private void OnCharacterHealCallback(string characterId, int heal, int currentHp)
    {
        Debug.Log($"角色治疗回调: {characterId}, 治疗: {heal}, 当前HP: {currentHp}");
        characterUI.ShowHeal(characterId, heal);
        characterUI.UpdateCharacterHP(characterId, currentHp);
    }
    
    private void OnBattleEndCallback(string battleId, object result)
    {
        Debug.Log($"战斗结束回调: {battleId}");
        isBattleActive = false;
        battleUI.ShowBattleEnd(result);
    }
    
    private void OnSkillEffectCallback(string characterId, string skillId, string targetId)
    {
        Debug.Log($"技能效果回调: {characterId} 使用 {skillId} 目标 {targetId}");
        skillUI.ShowSkillEffect(characterId, skillId, targetId);
    }
    
    private void OnStatusEffectCallback(string characterId, string effectName, bool applied)
    {
        Debug.Log($"状态效果回调: {characterId} {effectName} {(applied ? "施加" : "移除")}");
        characterUI.ShowStatusEffect(characterId, effectName, applied);
    }
    
    /// <summary>
    /// 清理Lua环境
    /// </summary>
    private void CleanupLuaEnvironment()
    {
        luaEnv?.Dispose();
        Debug.Log("Lua环境清理完成");
    }
}

/// <summary>
/// 战斗状态数据结构
/// </summary>
[System.Serializable]
public class BattleStateData
{
    public string battleId;
    public int currentTurn;
    public string battleState;
    public TeamData[] teams;
    public CharacterData currentCharacter;
    public TurnOrderData[] turnOrder;
}

/// <summary>
/// 队伍数据结构
/// </summary>
[System.Serializable]
public class TeamData
{
    public string name;
    public CharacterData[] characters;
    public int score;
}

/// <summary>
/// 角色数据结构
/// </summary>
[System.Serializable]
public class CharacterData
{
    public string id;
    public string name;
    public int level;
    public int teamId;
    public int position;
    public bool isAlive;
    public bool isControlled;
    public int maxHp;
    public int hp;
    public int maxMp;
    public int mp;
    public CharacterStats currentStats;
    public StatusEffectData[] statusEffects;
    public SkillData[] skills;
    public Dictionary<string, int> items;
}

/// <summary>
/// 角色属性数据结构
/// </summary>
[System.Serializable]
public class CharacterStats
{
    public int hp;
    public int mp;
    public int attack;
    public int defense;
    public int magicAttack;
    public int magicDefense;
    public int speed;
    public int luck;
}

/// <summary>
/// 状态效果数据结构
/// </summary>
[System.Serializable]
public class StatusEffectData
{
    public string name;
    public int duration;
    public int stacks;
}

/// <summary>
/// 技能数据结构
/// </summary>
[System.Serializable]
public class SkillData
{
    public string id;
    public string name;
    public int currentCooldown;
    public int maxCooldown;
    public int costMp;
    public bool isUsable;
}

/// <summary>
/// 行动顺序数据结构
/// </summary>
[System.Serializable]
public class TurnOrderData
{
    public string characterId;
    public string characterName;
    public int speed;
}

/// <summary>
/// 角色行动数据结构
/// </summary>
[System.Serializable]
public class CharacterActionData
{
    public string characterId;
    public string actionType;
    public string targetId;
    public object actionData;
}

/// <summary>
/// 战斗结果数据结构
/// </summary>
[System.Serializable]
public class BattleResultData
{
    public int winnerTeamId;
    public string reason;
    public BattleRewardsData rewards;
}

/// <summary>
/// 战斗奖励数据结构
/// </summary>
[System.Serializable]
public class BattleRewardsData
{
    public int exp;
    public int gold;
    public string[] items;
}